﻿using System.Linq;
using CID.Domain.Infrastructure;
using CID.Tests.Support;
using NUnit.Framework;

namespace CID.Domain.Persistence.Tests.Infrastructure
{
    [TestFixture]
    class TemplateTypePersistenceTests : BasePersistenceWithDataTests
    {
        private static void AssertAreEqual(TemplateType expected, TemplateType actual)
        {
            Assert.AreEqual(expected.Id, actual.Id);
            Assert.AreEqual(expected.Name, actual.Name);
            Assert.AreEqual(expected.Description, actual.Description);
            Assert.AreEqual(expected.TemplateContentEditorConverterType, actual.TemplateContentEditorConverterType);
            Assert.AreEqual(expected.TemplateContentEditorViewName, actual.TemplateContentEditorViewName);
            Assert.AreEqual(expected.Enabled, actual.Enabled);
            CollectionAssert.AreEquivalent(expected.Templates.Select(x => x.Id), actual.Templates.Select(x => x.Id));
        }

        [Test]
        public void SaveNewTemplateType_TemplateTypeShouldBeSaved()
        {
            var session = OpenSession();
            var newTemplateType = DataProvider.CreateTemplateType();
            session.SaveOrUpdate(newTemplateType);
            CleanSession(session);

            Assert.AreNotEqual(NotSavedId, newTemplateType.Id);
            session = OpenSession();
            var retrievedTemplateType = session.Get<TemplateType>(newTemplateType.Id);
            AssertAreEqual(newTemplateType, retrievedTemplateType);
            CleanSession(session);
        }

        [Test]
        public void SaveModifiedTemplateType_ChangesShouldBeSaved()
        {
            var session = OpenSession();
            var newTemplateType = DataProvider.CreateTemplateType();
            session.SaveOrUpdate(newTemplateType);
            var newTemplate= newTemplateType.CreateActivationTemplate(GetRandomString(), GetRandomString(), new byte[] { 1, 2, 3 });
            CleanSession(session);

            session = OpenSession();
            var modifiedTemplateType = session.Get<TemplateType>(newTemplateType.Id);
            AssertAreEqual(newTemplateType, modifiedTemplateType); //Necessary to load lazy collections before the session is wiped out
            modifiedTemplateType.ModifyProperty(x => x.Name);
            modifiedTemplateType.ModifyProperty(x => x.Description);
            modifiedTemplateType.ModifyProperty(x => x.TemplateContentEditorConverterType);
            modifiedTemplateType.ModifyProperty(x => x.TemplateContentEditorViewName);
            modifiedTemplateType.CreateActivationTemplate(GetRandomString(), GetRandomString(), new byte[] { 1, 2, 3 });
            modifiedTemplateType.RemoveTemplate(DataProvider.GetTemplate<ActivationTemplate>(session, newTemplate));
            modifiedTemplateType.ModifyProperty(x => x.Enabled);
            session.SaveOrUpdate(modifiedTemplateType);
            CleanSession(session);

            session = OpenSession();
            var retrievedTemplateType = session.Get<TemplateType>(newTemplateType.Id);
            AssertAreEqual(modifiedTemplateType, retrievedTemplateType);
            CleanSession(session);
        }

        [Test]
        public void DeleteTemplateType_TemplateTypeShouldBeDeleted()
        {
            var session = OpenSession();
            var newTemplateType1 = DataProvider.CreateTemplateType("Another TemplateType Name");
            var newTemplateType2 = DataProvider.CreateTemplateType();
            session.SaveOrUpdate(newTemplateType1);
            session.SaveOrUpdate(newTemplateType2);
            CleanSession(session);

            session = OpenSession();
            var retrievedTemplateType1 = session.Get<TemplateType>(newTemplateType1.Id);
            session.Delete(retrievedTemplateType1);
            CleanSession(session);

            session = OpenSession();
            retrievedTemplateType1 = session.Get<TemplateType>(newTemplateType1.Id);
            var retrievedTemplateType2 = session.Get<TemplateType>(newTemplateType2.Id);
            Assert.IsNull(retrievedTemplateType1);
            Assert.IsNotNull(retrievedTemplateType2);
            CleanSession(session);
        }
    }
}
